using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using HslCommunication.Core;
using HslCommunication.ModBus;
using HslCommunication.Profinet.Siemens;
using Opc.Ua;
using OpcUaHelper;
using WIT.DAQ.Core.Enums;
using WIT.DAQ.Core.Models;
using WIT.DAQ.Core.Protocols.Socket;

namespace WIT.DAQ.Core.Forms;

/// <summary>
/// 监控窗口
/// </summary>
internal class MonitorForm : BaseForm
{
	/// <summary>
	/// 自定义采集项（用于实时监控展示）
	/// </summary>
	private class MonitorDAQItem : DAQItem
	{
		/// <summary>
		/// 序号（用于查询展示）
		/// </summary>
		public int Index { get; set; }

		/// <summary>
		/// 实时监控值
		/// </summary>
		public object Value { get; set; }

		/// <summary>
		/// 获取到监控值的时间
		/// </summary>
		public string Time { get; set; }

		/// <summary>
		/// 设备名称
		/// </summary>
		public string DeviceName { get; set; }

		/// <summary>
		/// 地址（Address/NodeId）
		/// </summary>
		public string MonitorAddress { get; set; }
	}

	/// <summary>
	/// 标识是否正在监控数据
	/// </summary>
	private bool IS_MONITORING = false;

	/// <summary>
	/// 标识窗体是否正在关闭
	/// </summary>
	private bool IS_FORMCLOSING = false;

	/// <summary>
	/// 数据监视线程池
	/// </summary>
	private List<BackgroundWorker> MONITOR_BW_POOL = new List<BackgroundWorker>();

	/// <summary>
	/// 数据监视连接池
	/// </summary>
	private List<Connection> CONNECTION_POOL = new List<Connection>();

	/// <summary>
	/// Required designer variable.
	/// </summary>
	private IContainer components = null;

	private Button btnMonitor;

	private Label label1;

	private ComboBox cmbStations;

	private DataGridView dgvDAQItems;

	private CheckBox cbShowAddressColumn;

	private CheckBox cbShowDeviceColumn;

	private ContextMenuStrip cmsMonitor;

	private ToolStripMenuItem tsmiWriteValue;

	private NumericUpDown nudInterval;

	private Label label2;

	private Label label3;

	private Panel pnlInterval;

	private ToolStripMenuItem tsmiManualReadValue;

	private ToolStripSeparator tsSeparator;

	private ToolStripMenuItem tsmiDetail;

	private DataGridViewTextBoxColumn Index;

	private DataGridViewTextBoxColumn DeviceId;

	private DataGridViewTextBoxColumn DeviceName;

	private DataGridViewTextBoxColumn DAQItemName;

	private DataGridViewTextBoxColumn DataType;

	private DataGridViewTextBoxColumn ShowValue;

	private DataGridViewTextBoxColumn Value;

	private DataGridViewTextBoxColumn Time;

	private DataGridViewTextBoxColumn MonitorAddress;

	private DataGridViewTextBoxColumn Desc;

	/// <summary>
	/// 必须使用MainForm.MONITORFORM进行实例化
	/// </summary>
	/// <param name="station"></param>
	internal MonitorForm(Station station = null)
	{
		MethodBase method = new StackTrace(fNeedFileInfo: true).GetFrame(1).GetMethod();
		string fullName = new StackTrace(fNeedFileInfo: true).GetFrame(1).GetMethod().DeclaringType.FullName;
		string name = new StackTrace(fNeedFileInfo: true).GetFrame(1).GetMethod().Name;
		if (fullName != "WIT.DAQ.Core.Forms.BaseForm" || name != "ShowMonitorForm")
		{
			MessageBox.Show("仅允许从合法入口WIT.DAQ.Core.Forms.BaseForm.ShowMonitorForm()打开此窗口[" + base.Name + "]", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Hand);
			Environment.Exit(0);
		}
		InitializeComponent();
		dgvDAQItems.AutoGenerateColumns = false;
		btnMonitor.Visible = false;
		InitStations();
		base.Disposed += MonitorForm_Disposed;
		cmbStations.SelectedIndexChanged += cmbStations_SelectedIndexChanged;
		if (station != null)
		{
			cmbStations.SelectedValue = station.Id;
		}
	}

	private void MonitorForm_Load(object sender, EventArgs e)
	{
		nudInterval.Value = Common.MonitorInterval;
	}

	private void MonitorForm_Shown(object sender, EventArgs e)
	{
		if (Common.AutoMaximizeMonitor)
		{
			base.WindowState = FormWindowState.Maximized;
		}
		if (cmbStations.SelectedValue != null)
		{
			btnMonitor_Click(null, null);
		}
	}

	/// <summary>
	/// 加载站点
	/// </summary>
	private void InitStations()
	{
		List<Station> allStations = Common.GetAllStations();
		cmbStations.DataSource = allStations;
		cmbStations.DisplayMember = "Name";
		cmbStations.ValueMember = "Id";
		cmbStations.SelectedIndex = -1;
	}

	/// <summary>
	/// 加载采集项
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void cmbStations_SelectedIndexChanged(object sender, EventArgs e)
	{
		Text = "实时数据监控 - [" + cmbStations.Text + "]";
		List<DAQItem> dAQItems = Common.GetDAQItems(new Guid(cmbStations.SelectedValue.ToString()));
		BindingList<MonitorDAQItem> bindingList = new BindingList<MonitorDAQItem>();
		int num = 1;
		foreach (DAQItem item in dAQItems)
		{
			Device device = Common.GetDevice(item.DeviceId);
			bindingList.Add(new MonitorDAQItem
			{
				Id = item.Id,
				StationId = item.StationId,
				DeviceId = item.DeviceId,
				Name = item.Name,
				DataType = item.DataType,
				Address = item.Address,
				Length = item.Length,
				NodeId = item.NodeId,
				Desc = item.Desc,
				Index = num++,
				DeviceName = device.Name,
				MonitorAddress = ((device.Protocol == EnumProtocol.OPCUA) ? item.NodeId : item.Address)
			});
		}
		dgvDAQItems.DataSource = bindingList;
		btnMonitor.Visible = true;
	}

	/// <summary>
	/// 切换显示地址列
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void cbShowAddressColumn_CheckedChanged(object sender, EventArgs e)
	{
		dgvDAQItems.Columns["MonitorAddress"].Visible = cbShowAddressColumn.Checked;
	}

	/// <summary>
	/// 切换显示设备列
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void cbShowDeviceColumn_CheckedChanged(object sender, EventArgs e)
	{
		dgvDAQItems.Columns["DeviceName"].Visible = cbShowDeviceColumn.Checked;
	}

	/// <summary>
	/// 开始/停止监控
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void btnMonitor_Click(object sender, EventArgs e)
	{
		if (dgvDAQItems.Rows.Count == 0)
		{
			return;
		}
		if (IS_MONITORING)
		{
			StopMonitor();
			cmbStations.Enabled = true;
			nudInterval.Enabled = true;
			btnMonitor.Text = "开始监控(&S)";
			IS_MONITORING = false;
			return;
		}
		cmbStations.Enabled = false;
		nudInterval.Enabled = false;
		btnMonitor.Text = "停止监控(&C)";
		IS_MONITORING = true;
		foreach (DataGridViewRow item in (IEnumerable)dgvDAQItems.Rows)
		{
			item.Cells["ShowValue"].Value = null;
			item.Cells["Value"].Value = null;
			item.Cells["Time"].Value = null;
		}
		MONITOR_BW_POOL = new List<BackgroundWorker>();
		BindingList<MonitorDAQItem> source = (BindingList<MonitorDAQItem>)dgvDAQItems.DataSource;
		IEnumerable<Device> enumerable = from t in source.Select((MonitorDAQItem t) => t.DeviceId).Distinct()
			select Common.GetDevice(t);
		foreach (Device device in enumerable)
		{
			Thread thread = new Thread((ThreadStart)delegate
			{
				MonitorAsync(device);
			});
			thread.IsBackground = true;
			thread.Start();
		}
	}

	/// <summary>
	/// 停止监控
	/// </summary>
	private void StopMonitor()
	{
		foreach (BackgroundWorker item in MONITOR_BW_POOL)
		{
			item.CancelAsync();
			item.Dispose();
		}
		MONITOR_BW_POOL.Clear();
		foreach (Connection item2 in CONNECTION_POOL)
		{
			switch (item2.Protocol)
			{
			case EnumProtocol.OPCUA:
				(item2.ConnectionIns as OpcUaClient).Disconnect();
				break;
			case EnumProtocol.S7:
				(item2.ConnectionIns as SiemensS7Net).ConnectClose();
				break;
			case EnumProtocol.ModbusTcp:
				(item2.ConnectionIns as ModbusTcpNet).ConnectClose();
				break;
			case EnumProtocol.ModbusRtu:
				(item2.ConnectionIns as ModbusRtu).Close();
				break;
			case EnumProtocol.Socket:
				(item2.ConnectionIns as TCPClient).DisConnect();
				break;
			default:
				throw new Exception($"未知的通信协议[{item2.Protocol}]");
			}
		}
		CONNECTION_POOL.Clear();
	}

	/// <summary>
	/// 监控（创建连接池，并开启异步监控每个采集项）
	/// </summary>
	/// <param name="device">设备</param>
	private void MonitorAsync(Device device)
	{
		int monitorGroupSize = Common.MonitorGroupSize;
		ConnectDevice(device);
		if (!IS_MONITORING)
		{
			StopMonitor();
			return;
		}
		if (monitorGroupSize == 0)
		{
			List<DataGridViewRow> list = new List<DataGridViewRow>();
			foreach (DataGridViewRow item in (IEnumerable)dgvDAQItems.Rows)
			{
				if ((Guid)item.Cells["DeviceId"].Value == device.Id)
				{
					list.Add(item);
				}
			}
			BackgroundWorker backgroundWorker = new BackgroundWorker
			{
				WorkerSupportsCancellation = true
			};
			backgroundWorker.DoWork += MonitorDAQItems;
			MONITOR_BW_POOL.Add(backgroundWorker);
			backgroundWorker.RunWorkerAsync(list);
			return;
		}
		List<DataGridViewRow> list2 = new List<DataGridViewRow>();
		foreach (DataGridViewRow item2 in (IEnumerable)dgvDAQItems.Rows)
		{
			if ((Guid)item2.Cells["DeviceId"].Value == device.Id)
			{
				list2.Add(item2);
			}
		}
		List<DataGridViewRow> list3 = new List<DataGridViewRow>();
		for (int i = 0; i < list2.Count; i++)
		{
			list3.Add(list2[i]);
			if ((i == 0 && monitorGroupSize == 1) || (i > 0 && (i + 1) % monitorGroupSize == 0) || i == list2.Count - 1)
			{
				BackgroundWorker backgroundWorker2 = new BackgroundWorker
				{
					WorkerSupportsCancellation = true
				};
				backgroundWorker2.DoWork += MonitorDAQItems;
				MONITOR_BW_POOL.Add(backgroundWorker2);
				backgroundWorker2.RunWorkerAsync(list3.ToList());
				list3.Clear();
			}
		}
	}

	/// <summary>
	/// 异步监控单个设备的多个点位
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private async void MonitorDAQItems(object sender, DoWorkEventArgs e)
	{
		if (IS_FORMCLOSING)
		{
			return;
		}
		BackgroundWorker bw = (BackgroundWorker)sender;
		int interval = Convert.ToInt32(nudInterval.Value);
		List<DataGridViewRow> rows = (List<DataGridViewRow>)e.Argument;
		if (rows.Count == 0)
		{
			return;
		}
		Device device = Common.GetDevice((Guid)rows[0].Cells["DeviceId"].Value);
		List<object> structInstancesBuffer = new List<object>();
		while (!bw.CancellationPending)
		{
			try
			{
				object connectionIns = CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id).ConnectionIns;
				if (device.Protocol == EnumProtocol.OPCUA && !(connectionIns as OpcUaClient).Connected)
				{
					if (device.NeedAccount.HasValue && device.NeedAccount.Value)
					{
						(connectionIns as OpcUaClient).UserIdentity = new UserIdentity(device.Account, device.Pwd);
					}
					await (connectionIns as OpcUaClient).ConnectServer(device.Url);
				}
				if (!IS_MONITORING)
				{
					StopMonitor();
					break;
				}
				foreach (DataGridViewRow row2 in rows)
				{
					if (bw.CancellationPending)
					{
						return;
					}
					if (Common.ReadValues(connectionIns, device, new List<DAQItem> { (DAQItem)row2.DataBoundItem }, out var values, out var errMsg, structInstancesBuffer))
					{
						Type valueType = values[0].GetType();
						if (valueType.IsAutoClass)
						{
							row2.Cells["ShowValue"].Value = $"{values[0]} {{Object}}";
						}
						else if (values[0] is IList)
						{
							row2.Cells["ShowValue"].Value = valueType.Name + "[" + valueType.GenericTypeArguments[0].Name + "]";
						}
						else
						{
							row2.Cells["ShowValue"].Value = values[0];
						}
						row2.Cells["Value"].Value = values[0];
						row2.Tag = valueType;
					}
					else
					{
						row2.Cells["ShowValue"].Value = errMsg;
					}
					row2.Cells["Time"].Value = DateTime.Now.ToString("HH:mm:ss.fff");
					values = null;
					errMsg = null;
				}
			}
			catch (Exception ex2)
			{
				Exception ex = ex2;
				if (!bw.CancellationPending)
				{
					foreach (DataGridViewRow row in (IEnumerable)dgvDAQItems.Rows)
					{
						if ((Guid)row.Cells["DeviceId"].Value == device.Id)
						{
							row.Cells["ShowValue"].Value = ex.Message;
							row.Cells["Value"].Value = ex.Message;
							row.Cells["Time"].Value = DateTime.Now.ToString("HH:mm:ss.fff");
							Application.DoEvents();
						}
					}
				}
			}
			finally
			{
				structInstancesBuffer.Clear();
			}
			Thread.Sleep(interval);
		}
	}

	/// <summary>
	/// 连接设备，并将连接实例添加至连接池
	/// </summary>
	/// <param name="device">设备</param>
	private async void ConnectDevice(Device device)
	{
		switch (device.Protocol)
		{
		case EnumProtocol.OPCUA:
		{
			OpcUaClient opcuaConnection = null;
			if (CONNECTION_POOL.Any((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(OpcUaClient)))
			{
				opcuaConnection = (OpcUaClient)CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(OpcUaClient)).ConnectionIns;
			}
			else
			{
				opcuaConnection = new OpcUaClient();
				Invoke((Action)delegate
				{
					CONNECTION_POOL.Add(new Connection
					{
						DeviceId = device.Id,
						Protocol = EnumProtocol.OPCUA,
						ConnectionIns = opcuaConnection
					});
				});
			}
			if (!opcuaConnection.Connected)
			{
				if (device.NeedAccount.HasValue && device.NeedAccount.Value)
				{
					opcuaConnection.UserIdentity = new UserIdentity(device.Account, device.Pwd);
				}
				try
				{
					await opcuaConnection.ConnectServer(device.Url);
				}
				catch
				{
				}
			}
			break;
		}
		case EnumProtocol.S7:
		{
			SiemensS7Net s7Connection = null;
			if (CONNECTION_POOL.Any((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(SiemensS7Net)))
			{
				s7Connection = (SiemensS7Net)CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(SiemensS7Net)).ConnectionIns;
			}
			else
			{
				s7Connection = new SiemensS7Net((SiemensPLCS)device.Model)
				{
					IpAddress = device.IP,
					Port = device.Port,
					Rack = Convert.ToByte(device.Rack),
					Slot = Convert.ToByte(device.Slot)
				};
				Invoke((Action)delegate
				{
					CONNECTION_POOL.Add(new Connection
					{
						DeviceId = device.Id,
						Protocol = EnumProtocol.S7,
						ConnectionIns = s7Connection
					});
				});
			}
			s7Connection.ConnectServer();
			break;
		}
		case EnumProtocol.ModbusTcp:
		{
			ModbusTcpNet modbusConnection = null;
			if (CONNECTION_POOL.Any((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(ModbusTcpNet)))
			{
				modbusConnection = (ModbusTcpNet)CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(ModbusTcpNet)).ConnectionIns;
			}
			else
			{
				modbusConnection = new ModbusTcpNet(device.IP, device.Port, Convert.ToByte(device.Station))
				{
					AddressStartWithZero = device.AddressStartWithZero.Value,
					DataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), device.DataFormat, ignoreCase: true),
					IsStringReverse = device.IsStringReverse.Value
				};
				Invoke((Action)delegate
				{
					CONNECTION_POOL.Add(new Connection
					{
						DeviceId = device.Id,
						Protocol = EnumProtocol.ModbusTcp,
						ConnectionIns = modbusConnection
					});
				});
			}
			modbusConnection.ConnectServer();
			break;
		}
		case EnumProtocol.ModbusRtu:
		{
			ModbusRtu modbusConnection2 = null;
			if (CONNECTION_POOL.Any((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(ModbusRtu)))
			{
				modbusConnection2 = (ModbusRtu)CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(ModbusRtu)).ConnectionIns;
			}
			else
			{
				modbusConnection2 = new ModbusRtu(Convert.ToByte(device.Station))
				{
					AddressStartWithZero = device.AddressStartWithZero.Value,
					DataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), device.DataFormat, ignoreCase: true),
					IsStringReverse = device.IsStringReverse.Value
				};
				modbusConnection2.SerialPortInni(device.ComPort, Convert.ToInt32(device.BaudRate), Convert.ToInt32(device.DataBits), (StopBits)device.StopBits.Value, (Parity)device.Parity.Value);
				Invoke((Action)delegate
				{
					CONNECTION_POOL.Add(new Connection
					{
						DeviceId = device.Id,
						Protocol = EnumProtocol.ModbusRtu,
						ConnectionIns = modbusConnection2
					});
				});
			}
			modbusConnection2.Open();
			break;
		}
		case EnumProtocol.Socket:
			break;
		default:
			throw new Exception($"未知的通信协议[{device.Protocol}]");
		}
	}

	/// <summary>
	/// 右键选中行并显示菜单
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void dgvDAQItems_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
	{
		if (e.Button != MouseButtons.Right || e.RowIndex < 0 || e.ColumnIndex < 0)
		{
			return;
		}
		DataGridView dataGridView = (DataGridView)sender;
		dataGridView.ClearSelection();
		dataGridView.Rows[e.RowIndex].Selected = true;
		if (dgvDAQItems.SelectedRows[0].Tag != null)
		{
			if (dgvDAQItems.SelectedRows[0].Cells["Value"].Value is IList)
			{
				tsSeparator.Visible = true;
				tsmiDetail.Visible = true;
			}
			else if ((dgvDAQItems.SelectedRows[0].Tag as Type).IsAutoClass)
			{
				tsSeparator.Visible = true;
				tsmiDetail.Visible = true;
			}
			else
			{
				tsSeparator.Visible = false;
				tsmiDetail.Visible = false;
			}
		}
		else
		{
			tsSeparator.Visible = false;
			tsmiDetail.Visible = false;
		}
		cmsMonitor.Show(Control.MousePosition.X, Control.MousePosition.Y);
	}

	/// <summary>
	/// 右键菜单-写入值
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void tsmiWriteValue_Click(object sender, EventArgs e)
	{
		if (dgvDAQItems.SelectedRows[0].Tag != null)
		{
			Type type = (Type)dgvDAQItems.SelectedRows[0].Tag;
			if (type.IsArray || (!type.IsValueType && type != typeof(string)))
			{
				MessageBox.Show("非值类型或String，不允许直接写入！", "操作提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				return;
			}
		}
		Device device = Common.GetDevice(new Guid(dgvDAQItems.SelectedRows[0].Cells["DeviceId"].Value.ToString()));
		DAQItem daqItem = (DAQItem)dgvDAQItems.SelectedRows[0].DataBoundItem;
		object connectionIns = (CONNECTION_POOL.Any((Connection t) => t.DeviceId == device.Id) ? CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id).ConnectionIns : null);
		string defaultValue = ((dgvDAQItems.SelectedRows[0].Cells["Value"].Value == null) ? string.Empty : dgvDAQItems.SelectedRows[0].Cells["Value"].Value.ToString());
		WriteValueForm writeValueForm = new WriteValueForm(device, daqItem, defaultValue, connectionIns)
		{
			Icon = base.Icon,
			StartPosition = FormStartPosition.CenterParent
		};
		writeValueForm.ShowDialog();
	}

	/// <summary>
	/// 右键菜单-读取值
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void tsmiManualReadValue_Click(object sender, EventArgs e)
	{
		if (dgvDAQItems.SelectedRows.Count == 0)
		{
			return;
		}
		DataGridViewRow row = dgvDAQItems.SelectedRows[0];
		Device device = Common.GetDevice((Guid)row.Cells["DeviceId"].Value);
		Thread thread = new Thread((ThreadStart)delegate
		{
			if (!IS_MONITORING)
			{
				ConnectDevice(device);
			}
			object connectionIns = CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id).ConnectionIns;
			if (Common.ReadValues(connectionIns, device, new List<DAQItem> { (DAQItem)row.DataBoundItem }, out var values, out var errMsg, new List<object>()))
			{
				Type type = values[0].GetType();
				if (type.IsAutoClass)
				{
					row.Cells["ShowValue"].Value = $"{values[0]} {{Object}}";
				}
				else if (values[0] is IList)
				{
					row.Cells["ShowValue"].Value = type.Name + "[" + type.GenericTypeArguments[0].Name + "]";
				}
				else
				{
					row.Cells["ShowValue"].Value = values[0];
				}
				row.Cells["Value"].Value = values[0];
				row.Tag = values[0].GetType();
			}
			else
			{
				row.Cells["ShowValue"].Value = errMsg;
			}
			row.Cells["Time"].Value = DateTime.Now.ToString("HH:mm:ss.fff");
		});
		thread.IsBackground = true;
		thread.Start();
	}

	/// <summary>
	/// 双击行-写入值/查看对象的明细数据
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void dgvDAQItems_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
	{
		if (e.RowIndex < 0 || e.ColumnIndex < 0)
		{
			return;
		}
		if (dgvDAQItems.SelectedRows[0].Tag != null)
		{
			if (dgvDAQItems.SelectedRows[0].Cells["Value"].Value is IList)
			{
				tsmiDetail_Click(null, null);
			}
			else if ((dgvDAQItems.SelectedRows[0].Tag as Type).IsAutoClass)
			{
				tsmiDetail_Click(null, null);
			}
			else
			{
				tsmiWriteValue_Click(null, null);
			}
		}
		else
		{
			tsmiWriteValue_Click(null, null);
		}
	}

	/// <summary>
	/// 查看对象的详细数据
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void tsmiDetail_Click(object sender, EventArgs e)
	{
		DataGridViewRow dataGridViewRow = dgvDAQItems.SelectedRows[0];
		Device device = Common.GetDevice(new Guid(dataGridViewRow.Cells["DeviceId"].Value.ToString()));
		if (!IS_MONITORING)
		{
			ConnectDevice(device);
		}
		Connection connection = CONNECTION_POOL.FirstOrDefault((Connection t) => t.DeviceId == device.Id && t.ConnectionIns.GetType() == typeof(OpcUaClient));
		if (!((OpcUaClient)connection.ConnectionIns).Connected)
		{
			MessageBox.Show("设备[" + device.Name + "]连接失败！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
			return;
		}
		OpcUaClient opcuaConnection = (OpcUaClient)connection.ConnectionIns;
		DAQItem daqItem = (DAQItem)dataGridViewRow.DataBoundItem;
		object value = dataGridViewRow.Cells["Value"].Value;
		if (Common.DETAIL_FORM == null)
		{
			Common.DETAIL_FORM = new DetailForm(device, opcuaConnection, daqItem, Convert.ToInt32(nudInterval.Value), value)
			{
				Icon = base.Icon,
				StartPosition = FormStartPosition.Manual
			};
			Common.DETAIL_FORM.Disposed += delegate
			{
				Common.DETAIL_FORM = null;
			};
			Rectangle workingArea = Screen.GetWorkingArea(this);
			Common.DETAIL_FORM.Location = new Point(base.Location.X + (base.Width - Common.DETAIL_FORM.Width) / 2, base.Location.Y + (base.Height - Common.DETAIL_FORM.Height) / 2);
			Common.DETAIL_FORM.Show();
		}
		else
		{
			if (!Common.DETAIL_FORM.Visible)
			{
				Common.DETAIL_FORM.Visible = true;
			}
			if (Common.DETAIL_FORM.WindowState == FormWindowState.Minimized)
			{
				Common.DETAIL_FORM.WindowState = FormWindowState.Normal;
			}
			Common.DETAIL_FORM.Activate();
		}
	}

	private void MonitorForm_FormClosing(object sender, FormClosingEventArgs e)
	{
		IS_FORMCLOSING = true;
	}

	private void MonitorForm_Disposed(object sender, EventArgs e)
	{
		StopMonitor();
	}

	/// <summary>
	/// Clean up any resources being used.
	/// </summary>
	/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
	protected override void Dispose(bool disposing)
	{
		if (disposing && components != null)
		{
			components.Dispose();
		}
		base.Dispose(disposing);
	}

	/// <summary>
	/// Required method for Designer support - do not modify
	/// the contents of this method with the code editor.
	/// </summary>
	private void InitializeComponent()
	{
		this.components = new System.ComponentModel.Container();
		this.btnMonitor = new System.Windows.Forms.Button();
		this.label1 = new System.Windows.Forms.Label();
		this.cmbStations = new System.Windows.Forms.ComboBox();
		this.dgvDAQItems = new System.Windows.Forms.DataGridView();
		this.Index = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.DeviceId = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.DeviceName = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.DAQItemName = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.DataType = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.ShowValue = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.Value = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.Time = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.MonitorAddress = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.Desc = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.cbShowAddressColumn = new System.Windows.Forms.CheckBox();
		this.cbShowDeviceColumn = new System.Windows.Forms.CheckBox();
		this.cmsMonitor = new System.Windows.Forms.ContextMenuStrip(this.components);
		this.tsmiWriteValue = new System.Windows.Forms.ToolStripMenuItem();
		this.tsmiManualReadValue = new System.Windows.Forms.ToolStripMenuItem();
		this.tsSeparator = new System.Windows.Forms.ToolStripSeparator();
		this.tsmiDetail = new System.Windows.Forms.ToolStripMenuItem();
		this.nudInterval = new System.Windows.Forms.NumericUpDown();
		this.label2 = new System.Windows.Forms.Label();
		this.label3 = new System.Windows.Forms.Label();
		this.pnlInterval = new System.Windows.Forms.Panel();
		((System.ComponentModel.ISupportInitialize)this.dgvDAQItems).BeginInit();
		this.cmsMonitor.SuspendLayout();
		((System.ComponentModel.ISupportInitialize)this.nudInterval).BeginInit();
		this.pnlInterval.SuspendLayout();
		base.SuspendLayout();
		this.btnMonitor.Location = new System.Drawing.Point(289, 11);
		this.btnMonitor.Name = "btnMonitor";
		this.btnMonitor.Size = new System.Drawing.Size(80, 23);
		this.btnMonitor.TabIndex = 1;
		this.btnMonitor.Text = "开始监控(&S)";
		this.btnMonitor.UseVisualStyleBackColor = true;
		this.btnMonitor.Click += new System.EventHandler(btnMonitor_Click);
		this.label1.AutoSize = true;
		this.label1.Font = new System.Drawing.Font("宋体", 9f, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 134);
		this.label1.Location = new System.Drawing.Point(20, 16);
		this.label1.Name = "label1";
		this.label1.Size = new System.Drawing.Size(41, 12);
		this.label1.TabIndex = 5;
		this.label1.Text = "站点：";
		this.cmbStations.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
		this.cmbStations.Font = new System.Drawing.Font("宋体", 9f, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 134);
		this.cmbStations.FormattingEnabled = true;
		this.cmbStations.Location = new System.Drawing.Point(67, 12);
		this.cmbStations.Name = "cmbStations";
		this.cmbStations.Size = new System.Drawing.Size(216, 20);
		this.cmbStations.TabIndex = 0;
		this.dgvDAQItems.AllowUserToAddRows = false;
		this.dgvDAQItems.AllowUserToDeleteRows = false;
		this.dgvDAQItems.AllowUserToResizeRows = false;
		this.dgvDAQItems.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.dgvDAQItems.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
		this.dgvDAQItems.BackgroundColor = System.Drawing.SystemColors.Control;
		this.dgvDAQItems.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
		this.dgvDAQItems.Columns.AddRange(this.Index, this.DeviceId, this.DeviceName, this.DAQItemName, this.DataType, this.ShowValue, this.Value, this.Time, this.MonitorAddress, this.Desc);
		this.dgvDAQItems.Location = new System.Drawing.Point(-1, 38);
		this.dgvDAQItems.MultiSelect = false;
		this.dgvDAQItems.Name = "dgvDAQItems";
		this.dgvDAQItems.ReadOnly = true;
		this.dgvDAQItems.RowHeadersVisible = false;
		this.dgvDAQItems.RowTemplate.Height = 23;
		this.dgvDAQItems.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
		this.dgvDAQItems.Size = new System.Drawing.Size(986, 624);
		this.dgvDAQItems.TabIndex = 5;
		this.dgvDAQItems.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(dgvDAQItems_CellDoubleClick);
		this.dgvDAQItems.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(dgvDAQItems_CellMouseClick);
		this.Index.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
		this.Index.DataPropertyName = "Index";
		this.Index.FillWeight = 30f;
		this.Index.Frozen = true;
		this.Index.HeaderText = "序号";
		this.Index.MinimumWidth = 60;
		this.Index.Name = "Index";
		this.Index.ReadOnly = true;
		this.Index.Resizable = System.Windows.Forms.DataGridViewTriState.False;
		this.Index.Width = 60;
		this.DeviceId.DataPropertyName = "DeviceId";
		this.DeviceId.HeaderText = "DeviceId";
		this.DeviceId.Name = "DeviceId";
		this.DeviceId.ReadOnly = true;
		this.DeviceId.Visible = false;
		this.DeviceName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
		this.DeviceName.DataPropertyName = "DeviceName";
		this.DeviceName.HeaderText = "采集设备";
		this.DeviceName.MinimumWidth = 80;
		this.DeviceName.Name = "DeviceName";
		this.DeviceName.ReadOnly = true;
		this.DeviceName.Visible = false;
		this.DeviceName.Width = 150;
		this.DAQItemName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
		this.DAQItemName.DataPropertyName = "Name";
		this.DAQItemName.FillWeight = 89.54314f;
		this.DAQItemName.HeaderText = "采集项";
		this.DAQItemName.MinimumWidth = 100;
		this.DAQItemName.Name = "DAQItemName";
		this.DAQItemName.ReadOnly = true;
		this.DAQItemName.Width = 180;
		this.DataType.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
		this.DataType.DataPropertyName = "DataType";
		this.DataType.FillWeight = 50f;
		this.DataType.HeaderText = "数据类型";
		this.DataType.MinimumWidth = 80;
		this.DataType.Name = "DataType";
		this.DataType.ReadOnly = true;
		this.DataType.Width = 80;
		this.ShowValue.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
		this.ShowValue.DataPropertyName = "ShowValue";
		this.ShowValue.FillWeight = 89.54314f;
		this.ShowValue.HeaderText = "监控值";
		this.ShowValue.MinimumWidth = 100;
		this.ShowValue.Name = "ShowValue";
		this.ShowValue.ReadOnly = true;
		this.ShowValue.Width = 200;
		this.Value.DataPropertyName = "Value";
		this.Value.HeaderText = "Value";
		this.Value.Name = "Value";
		this.Value.ReadOnly = true;
		this.Value.Visible = false;
		this.Time.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
		this.Time.DataPropertyName = "Time";
		this.Time.HeaderText = "时间";
		this.Time.MinimumWidth = 80;
		this.Time.Name = "Time";
		this.Time.ReadOnly = true;
		this.MonitorAddress.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
		this.MonitorAddress.DataPropertyName = "MonitorAddress";
		this.MonitorAddress.HeaderText = "地址/NodeId";
		this.MonitorAddress.MinimumWidth = 100;
		this.MonitorAddress.Name = "MonitorAddress";
		this.MonitorAddress.ReadOnly = true;
		this.MonitorAddress.Width = 230;
		this.Desc.DataPropertyName = "Desc";
		this.Desc.FillWeight = 89.54314f;
		this.Desc.HeaderText = "采集项描述";
		this.Desc.MinimumWidth = 100;
		this.Desc.Name = "Desc";
		this.Desc.ReadOnly = true;
		this.cbShowAddressColumn.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
		this.cbShowAddressColumn.AutoSize = true;
		this.cbShowAddressColumn.Checked = true;
		this.cbShowAddressColumn.CheckState = System.Windows.Forms.CheckState.Checked;
		this.cbShowAddressColumn.Location = new System.Drawing.Point(888, 14);
		this.cbShowAddressColumn.Name = "cbShowAddressColumn";
		this.cbShowAddressColumn.Size = new System.Drawing.Size(84, 16);
		this.cbShowAddressColumn.TabIndex = 4;
		this.cbShowAddressColumn.Text = "显示地址列";
		this.cbShowAddressColumn.UseVisualStyleBackColor = true;
		this.cbShowAddressColumn.CheckedChanged += new System.EventHandler(cbShowAddressColumn_CheckedChanged);
		this.cbShowDeviceColumn.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
		this.cbShowDeviceColumn.AutoSize = true;
		this.cbShowDeviceColumn.Location = new System.Drawing.Point(798, 14);
		this.cbShowDeviceColumn.Name = "cbShowDeviceColumn";
		this.cbShowDeviceColumn.Size = new System.Drawing.Size(84, 16);
		this.cbShowDeviceColumn.TabIndex = 3;
		this.cbShowDeviceColumn.Text = "显示设备列";
		this.cbShowDeviceColumn.UseVisualStyleBackColor = true;
		this.cbShowDeviceColumn.CheckedChanged += new System.EventHandler(cbShowDeviceColumn_CheckedChanged);
		this.cmsMonitor.Items.AddRange(new System.Windows.Forms.ToolStripItem[4] { this.tsmiWriteValue, this.tsmiManualReadValue, this.tsSeparator, this.tsmiDetail });
		this.cmsMonitor.Name = "cmsMonitor";
		this.cmsMonitor.Size = new System.Drawing.Size(142, 76);
		this.tsmiWriteValue.Name = "tsmiWriteValue";
		this.tsmiWriteValue.Size = new System.Drawing.Size(141, 22);
		this.tsmiWriteValue.Text = "写入值(&W)";
		this.tsmiWriteValue.Click += new System.EventHandler(tsmiWriteValue_Click);
		this.tsmiManualReadValue.Name = "tsmiManualReadValue";
		this.tsmiManualReadValue.Size = new System.Drawing.Size(141, 22);
		this.tsmiManualReadValue.Text = "手动读取(&R)";
		this.tsmiManualReadValue.Click += new System.EventHandler(tsmiManualReadValue_Click);
		this.tsSeparator.Name = "tsSeparator";
		this.tsSeparator.Size = new System.Drawing.Size(138, 6);
		this.tsmiDetail.Name = "tsmiDetail";
		this.tsmiDetail.Size = new System.Drawing.Size(141, 22);
		this.tsmiDetail.Text = "查看明细(&D)";
		this.tsmiDetail.Click += new System.EventHandler(tsmiDetail_Click);
		this.nudInterval.Increment = new decimal(new int[4] { 100, 0, 0, 0 });
		this.nudInterval.Location = new System.Drawing.Point(69, 0);
		this.nudInterval.Maximum = new decimal(new int[4] { 600000, 0, 0, 0 });
		this.nudInterval.Minimum = new decimal(new int[4] { 100, 0, 0, 0 });
		this.nudInterval.Name = "nudInterval";
		this.nudInterval.Size = new System.Drawing.Size(80, 21);
		this.nudInterval.TabIndex = 2;
		this.nudInterval.Value = new decimal(new int[4] { 1000, 0, 0, 0 });
		this.label2.AutoSize = true;
		this.label2.Location = new System.Drawing.Point(155, 4);
		this.label2.Name = "label2";
		this.label2.Size = new System.Drawing.Size(17, 12);
		this.label2.TabIndex = 7;
		this.label2.Text = "ms";
		this.label3.AutoSize = true;
		this.label3.Location = new System.Drawing.Point(22, 4);
		this.label3.Name = "label3";
		this.label3.Size = new System.Drawing.Size(41, 12);
		this.label3.TabIndex = 8;
		this.label3.Text = "频率：";
		this.pnlInterval.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
		this.pnlInterval.Controls.Add(this.nudInterval);
		this.pnlInterval.Controls.Add(this.label2);
		this.pnlInterval.Controls.Add(this.label3);
		this.pnlInterval.Location = new System.Drawing.Point(603, 11);
		this.pnlInterval.Name = "pnlInterval";
		this.pnlInterval.Size = new System.Drawing.Size(189, 21);
		this.pnlInterval.TabIndex = 9;
		base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 12f);
		base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
		base.ClientSize = new System.Drawing.Size(984, 661);
		base.Controls.Add(this.pnlInterval);
		base.Controls.Add(this.cbShowDeviceColumn);
		base.Controls.Add(this.cbShowAddressColumn);
		base.Controls.Add(this.dgvDAQItems);
		base.Controls.Add(this.btnMonitor);
		base.Controls.Add(this.label1);
		base.Controls.Add(this.cmbStations);
		this.MinimumSize = new System.Drawing.Size(800, 500);
		base.Name = "MonitorForm";
		this.Text = "实时数据监控";
		base.FormClosing += new System.Windows.Forms.FormClosingEventHandler(MonitorForm_FormClosing);
		base.Load += new System.EventHandler(MonitorForm_Load);
		base.Shown += new System.EventHandler(MonitorForm_Shown);
		((System.ComponentModel.ISupportInitialize)this.dgvDAQItems).EndInit();
		this.cmsMonitor.ResumeLayout(false);
		((System.ComponentModel.ISupportInitialize)this.nudInterval).EndInit();
		this.pnlInterval.ResumeLayout(false);
		this.pnlInterval.PerformLayout();
		base.ResumeLayout(false);
		base.PerformLayout();
	}
}
